<?php
namespace addons\weixin\library;

use app\admin\model\weixin\Reply as WechatReply;
use app\admin\model\weixin\News as WechatNews;
use EasyWeChat\Kernel\Messages\Image;
use EasyWeChat\Kernel\Messages\Material;
use EasyWeChat\Kernel\Messages\News;
use EasyWeChat\Kernel\Messages\NewsItem;
use EasyWeChat\Kernel\Messages\Text;
use EasyWeChat\Kernel\Messages\Video;
use EasyWeChat\Kernel\Messages\Voice;
use EasyWeChat\Kernel\Messages\Transfer;
use EasyWeChat\Kernel\Messages\Media;

class Event
{
    /**
     * @notes 微信公众行为监听
     * @author 兴
     * @date 2022/10/31 15:27
     */
    public static function hook($server)
    {
        $server->push(function ($message)
        {
            //微信消息前置操作
            if ($message['MsgType'] == 'event')
            {
                switch (strtolower($message['Event'])) {
                    case 'subscribe':
                        $response = self::reply('subscribe');//关注回复
                        break;
                    case 'unsubscribe'://用户取消关注公众号前置操作
                        break;
                    case 'scan':
                        $response = self::reply('subscribe');//扫码关注
                        break;
                    case 'click':
                        $response = self::reply($message['EventKey']);//点击事件
                        break;
                }
            }
            elseif ($message['MsgType'] == 'text')
            {
                $response = self::reply($message['Content']);
            }
            return $response ?? false;
        });
    }

    /**
     * @notes 关键词回复
     * @author 兴
     * @date 2022/10/31 15:42
     */
    public static function reply($keyword)
    {
        $item = WechatReply::where('find_in_set("' . $keyword . '",keyword)')->where('status', 'normal')->find();
        if (empty($item)) {
            $item = WechatReply::where('keyword', 'default')->where('status', 'normal')->find();
        }
        if (empty($item)) {
            return self::transfer(); // 多客服消息转发
        }

        $content = json_decode($item->content, true);
        switch ($item->reply_type) {
            case 'text':
                if (isset($content['text']) && $content['text']) {
                    return self::textMessage($content['text']);
                }
                break;
            case 'news':
                if (isset($content['news']) && $content['news'] && is_numeric($content['news'])) {
                    $data = WechatNews::get($content['news']);
                    if (!empty($data)) {
                        return self::newsMessage($data);
                    }
                }
                break;
            case 'image':
                if (isset($content['image_media_id']) && $content['image_media_id']) {
                    return self::imageMessage($content['image_media_id']);
                }
                break;
            case 'voice':
                if (isset($content['voice_media_id']) && $content['voice_media_id']) {
                    return self::voiceMessage($content['voice_media_id']);
                }
                break;
            case 'video':
                if (isset($content['video_media_id']) && $content['video_media_id']) {
                    return self::videoMessage($content['video_media_id'], $content['video_title'], $content['video_description']);
                }
                break;
        }

        return self::textMessage('未找到匹配的关键词且未设置万能回复');
    }

    /**
     * 回复文本消息
     * @param string $content 文本内容
     * @return Text
     */
    public static function textMessage($content)
    {
        return new Text($content);
    }

    /**
     * 回复图文消息
     * @param string|array $title 标题
     * @param string $description 描述
     * @param string $url URL
     * @param string $image 图片链接
     * @return Video
     */
    public static function newsMessage($data)
    {
        $items = [
            new NewsItem([
                'title'       => $data['title'] ?? '',
                'description' => $data['description'] ?? '',
                'url'         => $data['url'] ?? '',
                'image'       => cdnurl($data['pic'], true),
            ]),
        ];
        return new News($items);
    }

    /**
     * 回复图片消息
     * @param string $media_id 媒体资源 ID
     * @return Image
     */
    public static function imageMessage($media_id)
    {
        return new Image($media_id);
    }

    /**
     * 回复视频消息
     * @param string $media_id 媒体资源 ID
     * @param string $title 标题
     * @param string $description 描述
     * @param null $thumb_media_id 封面资源 ID
     * @return Video
     */
    public static function videoMessage($media_id, $title = '', $description = '...', $thumb_media_id = null)
    {
        return new Video(
            $media_id,
            ['title' => $title, 'description' => $description, 'thumb_media_id' => $thumb_media_id]
        );
    }

    /**
     * 回复声音消息
     * @param string $media_id 媒体资源 ID
     * @return Voice
     */
    public static function voiceMessage($media_id)
    {
        return new Voice($media_id);
    }

    /**
     * 作为客服消息发送
     * @param $to
     * @param $message
     * @return bool
     */
    public static function staffTo($to, $message)
    {
        $staff = WechatService::application()->customer_service;
        $staff = is_callable($message) ? $staff->message($message()) : $staff->message($message);
        $res = $staff->to($to)->send();
        return $res;
    }

    /**
     * @notes 多客服消息转发
     * @author 兴
     * @date 2022/10/31 15:48
     */
    public function transfer()
    {
        return new Transfer();
    }

    /**
     * 上传永久素材接口
     * @return object
     */
    public static function material($type, $data)
    {
        switch ($type) {
            case 'image':
                $material = WechatService::application()->material->uploadImage($data);
                break;
            case 'voice':
                $material = WechatService::application()->material->uploadVoice($data);
                break;
            case 'video':
                $material = WechatService::application()->material->uploadVideo($data['file'], $data['title'], $data['description']);
                break;
        }
        return isset($material['media_id']) ? $material['media_id'] : 0;
    }

    /**
     * 客服消息接口
     * @return object
     */
    public static function staffService()
    {
        return WechatService::application()->customer_service;
    }

    /**
     * 回复素材消息
     * @param string $type [mpnews、 mpvideo、voice、image]
     * @param string $media_id 素材 ID
     * @return Material
     */
    public static function materialMessage($type, $media_id)
    {
        return new Media($media_id, $type);
    }
}
